<num> <id> (not follow by a '(')are valid expressions. The result of these expressions is simply the value of the number respectively the variable. Also a single string can be an expression:
<string>
Brand new are the mathematical constant expressions:
~<id>The Parser simply searches for a known constant <id> and replaces it by the corresponding value. Known constants are:
~pi Yust Pi (that thing with the diameter and the circumfence) ~e Yust e (the Euler constant) ~log2e this is log_2 e ~log10e this is log_10 e ~ln this is ln 2 respectively log_e 2 ~ln10 this is ln 10 respectively log_e 10 ~pi_2 this is pi/2 ~pi_4 this is pi/4 ~1_pi this is 1/pi ~2_pi this is 2/pi ~sqrt2 this is sqrt(2) ~sqrt1_2 this is 1/sqrt(2)... and a couple more out of math.h .
If the variable is an array there are two equivalent ways to get an element of this array:
<id> [ <expr> , <expr> , ...] <id> [ <expr> ] [ <expr> ]...Where the ... means at least one or more, and <expr> is another expression. Of course strings are not allowed at this point, but you can make any type of calculation here. For example: a[5,10],a[5,2*5],a[5][10] are valid expressions with the same result (see Calculation Expressions below).
Sometimes you may not only want a single element but a whole subarray of a bigger array. For this purpose a special index access does exist:
<id> [ <expr1> .. <expr2> ,... ] <id> [ <expr1> .. <expr2> : <expr3> ,... ] <id> [ * ,... ]The * represents the whole row where <expr1>..<expr2> <expr1> defines the lower bound, <expr2> the upperbound of a row and <expr1>..<expr2>:<expr3>. You can additionally define a stepsize <expr3> for that row (at the moment <expr3> must be greater or equal one, and <expr2> should be greater or equal <expr1>).
If this index access still dosn't satisfy you Xi can also perform a where access:
<id> [ where <expr> ]Here the result of <expr> is an integer array containing the indices of the array <id>. Usually <expr> is a Comparison between arrays.
<id> ( )The () are essential at this point, they are the only way for the Parser to distinguish between a variable and a function. If and <id> are followed by a '(' . The Parser seeks for a function with that name or otherwise for a variable.
The above rule describes the function call to a function with no parameter. Usually a function may have several parameters that have to be set by arguments in the function call:
<id> ( <expr1> , <expr2> ,...)<expr1>,<expr2>,... are the arguments of the functions.
So far we are C compatible. In C the order of the function arguments is fixed. There is actually no way to set the first parameter with the second argument and vice versa. For this purpose Xi has named arguments:
<id> ( \ <id1> = <expr1> , \ <id2> = <expr2> ,...)That means: The parameter <id1> of function <id> is set to the result of <expr1>, the parameter <id2>is set to the result of <expr2> and so on. In this way you can control the order of calculations of a function call's arguments (if you need dirty stuff like this). Xi first calculates <expr1>, then <expr2> and so on.
Furthermore the named arguments are useful if the function has flags.
<id> ( \ <id1> , \ <id2> ,...)will be translated to
<id> ( \ <id1> = 1 , \ <id2> = 1 ,...)which means that the parameters <id1>, <id2>,... of function <id> are all set to one respectively to true (since Xi has no boolean type a nonzero integer is true and zero is false. See Compare Expressions for more detail)
- <expr> (unary minus) <expr1> + <expr2> <expr1> - <expr2> <expr1> * <expr2> <expr1> / <expr2> ( <expr> )Note that these operators have the same precendencs as in C, i.e.: An expression 4*5+1 will be evaluated as (4*5)+1, and 4/-1+5 will be evaluated as (4/(-1))+5. Also the operators are left-associative, i.e.: An expression 1-2-3 will be evaluated as (1-2)-3 and 4/5*6 will be evaluated as (4/5)*6. If you want more informations consult a C introduction. Please keep in mind though that in Xi all operations also work on arrays e.g. you can add an array with a scalar or two arrays with the same dimensions.
In Addition to these standard operations Xi has a special matrix multiplication for arrays:
<expr1> # <expr2> <expr1> ## <expr2> <expr1> ### <expr2> . . .The first operation is a simple matrix multiplication between an nxm matrix <expr1> and a mxk matrix <expr2>, the second operation will multiply a (...,m,k)-tensor with a (m,k,...)-tensor by summing over the two inner indices. The third will multiply a (...,n,m,k)-tensor with a (n,m,k,...)-tensor by summing over the three inner indizes and so on.
If you want to calculate with complex numbers, you certainly want to enter the real and imaginary part of this number directly.
( <expr1> , <expr2> )This expression also works if <expr1> and <expr2> are arrays with the same dimenstions.
If you want to build up an array element by element, Xi offers you the folling expression:
{ <expr1> , <expr2> , ... , <exprn> }If <expr1> to <exprn> are scalars (i.e. no arrays) the above expression will generate a n-dimensional vector with corresponding entries. If <expr1> to <exprn> are all m-dimensional vectors the expression will generate a nxm matrix and so on. In this way it is possible to construct the wildest arrays you can think of.
Sometimes it comes handy to cast a double value into an integer an vice versa. In Xi there are two equivalent ways to cast a value to a specific type:
( <type> ) <expr> <type> ( <expr> )The first possibility is C compatible the second is the C++ way - pick one.
<expr1> == <expr2> <expr1> != <expr2> <expr1> < <expr2> <expr1> <= <expr2> <expr1> > <expr2> <expr1> >= <expr2>are all implented comparisons between two expressions. If <expr1> and <expr2> are scalars the above expressions should be clear, they can be found in every common C-introduction. If one or both are arrays Xi will compare an array with a scalar or two arrays element by element. The result is an array of integers filled with the indices of the array where the comparison is true.
Besides the pure comparisons there also exist logical operations usually used in connection with comparisons:
<expr1> && <expr2> <expr1> || <expr2>If <expr1> and <expr2> are simple comparisons between scalars these two operators act in the same way as in C. If <expr1> and <expr2> are both comparisons between arrays && (||) takes the union (cut) of the two resulting index arrays (see above).
<id> = <expr>which sets the variable <id> to the result of <expr>. The result of the whole expression is the new value of the Variable. Note that = is a right-associative operator, i.e. an input a=b=c=3 will be interpreted as a=(b=(c=3)) or, in human words, first set variable c to 3. Then set variable b to the result of this assignment (which is the new value of c and therefore also 3). Finally the a to the result of the last assignment (which is the new value of b; 3). Consequently a, b and c are all set to the value 3.
Assignments are also defined to set one or more elements of an array:
<id> [ <indx> ] = <expr> <id> [ where <expr> ] = <expr>Where <indx> means a list of indices which may contain ranges.
Like in C there the folling operations that directly act on variables exist:
<id> += <expr> <id> -= <expr> <id> *= <expr> <id> /= <expr> <id> ++ <id> -- ++ <id> -- <id>All these operations act in the same way as in C except that in Xi they also work on arrays. +=,-=,*= and /= add, subtract, multiply respectively divide the variable <id> by the result of <expr>. As in the previous case the result of the whole expression is the new value of <id>. ++ and -- increments respectively decrements the variable <id> by one. The result of this operation depends on whether ++ or -- stands before or after <id>. In the first case the result is the new value of <id> in the latter it is the old value of <id>. For a more detailed description have a look into a C-introduction.
The operation from above also works with elements of an array:
<id> [ <indx> ] += <expr> <id> [ where <expr> ] += <expr> <id> [ <indx> ] -= <expr> <id> [ where <expr> ] -= <expr> <id> [ <indx> ] *= <expr> <id> [ where <expr> ] *= <expr> <id> [ <indx> ] /= <expr> <id> [ where <expr> ] /= <expr> <id> [ <indx> ] ++ <id> [ where <expr> ] ++ <id> [ <indx> ] -- <id> [ where <expr> ] -- ++ <id> [ <indx> ] ++ <id> [ where <expr> ] -- <id> [ <indx> ] -- <id> [ where <expr> ]
In addition to these standard assignments Xi also has an extended assignment to set the values of several variables at once:
[ <id1> , <id2> ,... ] = [ <expr1> , <expr2> ,.. . ]With this the variable <id1> will be set to the result of <expr1>, <id2> to the result of <expr2> and so on. The result of the whole expression is the new value of <id1>. This assignment is not useful under normal circumstances with the exception of a function having more than one return value.
[ <id1> , <id2> ,... ] = <id_f> ( <args> )Here the Variables <id1>, <id2>, ... will be set to the results of the function <id_f ( args means the arguments of this functions; see Function calls for more detail).